package com.alibaba.citrus.ots.b2b.trade.order.functions.orderLine.factory;

import com.alibaba.citrus.ots.b2b.trade.order.facade.service.SandOutGoodsServiceImpl;
import com.alibaba.citrus.ots.b2b.trade.order.repository.OrderLineQueryServiceRepository;
import com.alibaba.citrus.ots.b2b.trade.order.functions.orderLine.entity.OrderLineWriteEntity;
import com.alibaba.citrus.ots.b2b.trade.order.functions.utils.OrderLineRemoveConverter;
import com.alibaba.citrus.ots.b2b.trade.order.functions.utils.SaveOrderLineConverter;
import com.alibaba.citrus.ots.common.annotation.FunctionInvoker;
import com.alibaba.citrus.ots.common.constant.SaleOrderConstants;
import com.alibaba.citrus.ots.common.exception.FunctionException;
import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.citrus.ots.common.util.SpringContextUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.epoch.app.otsb2btradecenter.dto.Packagedetails;
import com.epoch.app.otsb2btradecenter.dto.request.*;
import com.epoch.app.otsb2btradecenter.sdo.OrderLineSDO;
import com.epoch.app.otsb2btradecenter.sdo.OrderSDO;
import org.apache.commons.collections.FunctorException;
import org.apache.commons.collections.MapUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

public class OrderLineWriteFactory {

    private static Log log = Log.getLogger(OrderLineWriteFactory.class);

    private static OrderLineQueryServiceRepository orderLineQueryServiceRepository;

    static {
        orderLineQueryServiceRepository = SpringContextUtil.getBean(OrderLineQueryServiceRepository.class);
    }

    public static List<OrderLineWriteEntity> removeOrderLine(OrderLineRemoveRequest request) {
        List<OrderLineSDO> orderLineSDOS = OrderLineRemoveConverter.orderLineRemoveConverter(request);
        List<OrderLineWriteEntity> orderLineWriteEntities = orderLineSDOS.stream().map(orderLineSDO ->
        {
            OrderLineWriteEntity orderLineWriteEntity = OrderLineWriteEntity.of(orderLineSDO);
            return orderLineWriteEntity;
        }).collect(Collectors.toList());
        return orderLineWriteEntities;
    }

    public static List<OrderLineWriteEntity> saveOrderLine(OrderLineSaveRequest request) {
        List<OrderLineWriteEntity>  orderLineWriteEntities = new ArrayList<>();
        List<OrderLineSaveInnerRequest> orderLineSaveInnerRequest = request.getOrderDetailList();
        for (OrderLineSaveInnerRequest lineSaveInnerRequest : orderLineSaveInnerRequest) {
            OrderLineSDO orderLineSDO = SaveOrderLineConverter.converterOrderLineSDO(lineSaveInnerRequest);
            orderLineSDO.setMainOrderId(request.getId());
            OrderLineWriteEntity orderLineWriteEntity = OrderLineWriteEntity.of(orderLineSDO);
            orderLineWriteEntities.add(orderLineWriteEntity);
        }
        return orderLineWriteEntities;
    }

    public static OrderLineWriteEntity modifyOrderLine(OrderLineModifyRequest request) {
        OrderLineSDO orderLineSDO = OrderLineRemoveConverter.orderLineModifyConverter(request);
        return OrderLineWriteEntity.of(orderLineSDO);
    }


    @FunctionInvoker
    public static List<OrderLineWriteEntity> modifyStatus(SendOutGoodsRequest request, OrderSDO orderSDO) {

        List<OrderLineSDO> orderLineSDOS = new ArrayList<>();

        if (!CollectionUtils.isEmpty(request.getPackageDetailsList()) && !CollectionUtils.isEmpty(orderSDO.getOrderLineSDOS())) {
            for (Packagedetails packageDetails : request.getPackageDetailsList()) {
                if (!MapUtils.isEmpty(packageDetails.getOrderLineQuantity())) {
                    for (String key : packageDetails.getOrderLineQuantity().keySet()) {
                        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                            if (!StringUtils.isEmpty(orderLineSDO.getOuterOrderLineId())) {
                                if (key.equals(orderLineSDO.getOuterOrderLineId())) {
                                    //发货日期
                                    Map<String,String> lineMap = orderLineSDO.getFeatures();
                                    if (MapUtils.isEmpty(lineMap)){
                                        lineMap = new HashMap<>();
                                    }
                                    lineMap.put(SaleOrderConstants.DELIVERY_ORDER_DATE, DateUtils.toDateStr(DateUtils.string2Date(request.getPostingTime()), DateUtils.PATTEN_YMD));
                                    orderLineSDO.setFeatures(lineMap);
                                    //发货数量
                                    BigDecimal a = new BigDecimal(packageDetails.getOrderLineQuantity().get(key));
                                    int shippedQuantity = a.multiply(new BigDecimal(1000)).intValue();
//                                    int shippedQuantity = Integer.parseInt(sendGoodsQuantity);
                                    //货品数量
                                    Integer quantity = (orderLineSDO.getScItemSDO().getQuantity()*1000);
                                    //剩余未发货数量
                                    int surplusQuantity = quantity;
                                    if (!StringUtils.isEmpty(orderLineSDO.getDeliveryAmount())) {
                                        //交货数量
                                        BigDecimal b = new BigDecimal(orderLineSDO.getDeliveryAmount());
                                        int deliveryAmount = b.multiply(new BigDecimal(1000)).intValue();
                                        surplusQuantity = quantity - deliveryAmount;

                                    }
                                    if (shippedQuantity == surplusQuantity) {
                                        OrderLineSDO orderLineSDOOne = OrderLineRemoveConverter.converterStatus(orderLineSDO);
                                        setDeliveryAmount(shippedQuantity, orderLineSDOOne);
                                        orderLineSDOS.add(orderLineSDOOne);
                                    }
                                    if (shippedQuantity < surplusQuantity) {
                                        OrderLineSDO orderLineSDOOne = OrderLineRemoveConverter.converterStatusOne(orderLineSDO);
                                        setDeliveryAmount(shippedQuantity, orderLineSDOOne);
                                        orderLineSDOS.add(orderLineSDOOne);
                                    }
                                    if (shippedQuantity > surplusQuantity) {
                                       //modify by myw,20220622 产品需求
                                       // remove superfluous exception throw
                                        OrderLineSDO orderLineSDOOne = OrderLineRemoveConverter.converterStatus(orderLineSDO);
                                        setDeliveryAmount(shippedQuantity, orderLineSDOOne);
                                        orderLineSDOS.add(orderLineSDOOne);
                                        log.info("orderLine:"+JSONObject.toJSONString(orderLineSDOOne)+"发货数量shippedQuantity:" + shippedQuantity + "交货数量surplusQuantity:" + surplusQuantity);
                                       // throw new FunctionException("OTS-05-001-10-16-009");
                                    }

                                }

                            }else{
                                throw  new FunctionException("OTS-05-001-10-16-024");
                            }

                        }
                    }
                }
            }

        }

        if (CollectionUtils.isEmpty(orderLineSDOS)) {
            log.info("orderLineSDOS 外部单号对应的子单:"+ JSONObject.toJSONString(orderLineSDOS));
            throw new FunctionException("OTS-05-001-10-16-027");
        }

        return orderLineSDOS.stream().map(orderLineSDO -> {
            return OrderLineWriteEntity.of(orderLineSDO);
        }).collect(Collectors.toList());

    }

    private static void setDeliveryAmount(int shippedQuantity, OrderLineSDO orderLineSDOOne) {
        if (!StringUtils.isEmpty(orderLineSDOOne.getDeliveryAmount())) {
            BigDecimal a = new BigDecimal(orderLineSDOOne.getDeliveryAmount());
            int deliveryAmount = a.multiply(new BigDecimal(1000)).intValue();
            int i = shippedQuantity + deliveryAmount;
            String s = new BigDecimal(i).divide(new BigDecimal(1000), 3, BigDecimal.ROUND_DOWN).toString();
            orderLineSDOOne.setDeliveryAmount(s);
        } else if (StringUtils.isEmpty(orderLineSDOOne.getDeliveryAmount())) {
            String s = new BigDecimal(shippedQuantity).divide(new BigDecimal(1000), 3, BigDecimal.ROUND_DOWN).toString();
            orderLineSDOOne.setDeliveryAmount(s);
        }
    }


    public static List<OrderLineWriteEntity> chargeAgainstStatus(SendOutGoodsRequest request, OrderSDO orderSDO) {
        List<OrderLineSDO> orderLineList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(request.getPackageDetailsList()) && !CollectionUtils.isEmpty(orderSDO.getOrderLineSDOS())) {
            for (Packagedetails packageDetails : request.getPackageDetailsList()) {
                if (!MapUtils.isEmpty(packageDetails.getOrderLineQuantity())) {
                    for (String key : packageDetails.getOrderLineQuantity().keySet()) {
                        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                            if (!StringUtils.isEmpty(orderLineSDO.getScItemSDO().getScItemId())) {
                                if (key.equals(orderLineSDO.getOuterOrderLineId())) {
                                    //冲销数量
                                    String s = packageDetails.getOrderLineQuantity().get(key);
                                    if (StringUtils.isEmpty(s)) {
                                        throw new FunctionException("OTS-05-001-10-16-012");
                                    }
                                    Double chargeAgainstQuantity1 = Double.valueOf(s);
                                    // 冲销货品数量为0,跳过
                                    if (chargeAgainstQuantity1 == 0d) {
                                        continue;
                                    }
                                    //子单的交货数量
                                    BigDecimal a = new BigDecimal(orderLineSDO.getDeliveryAmount() == null?"0":orderLineSDO.getDeliveryAmount());
                                    int deliveryAmount = a.multiply(new BigDecimal(1000)).intValue();
                                    BigDecimal b = new BigDecimal(s);
                                    int chargeAgainstQuantity = b.multiply(new BigDecimal(1000)).intValue();
                                    if (chargeAgainstQuantity > deliveryAmount) {
                                        log.info("chargeAgainstQuantity:"+chargeAgainstQuantity);
                                        throw new FunctionException("OTS-05-001-10-16-013");
                                    }
                                    // 子单发货数量为空,状态置为待交货
                                    if (StringUtils.isEmpty(orderLineSDO.getDeliveryAmount())) {
                                        OrderLineSDO orderLineDelivery = OrderLineRemoveConverter.converterStatusDelivery(orderLineSDO);
                                        orderLineList.add(orderLineDelivery);
                                    } else {
                                        if (chargeAgainstQuantity == deliveryAmount) {
                                            OrderLineSDO orderLineDelivery = OrderLineRemoveConverter.converterStatusDelivery(orderLineSDO);
                                            setDeliveryChargeAgainstAmount(chargeAgainstQuantity, orderLineDelivery);
                                            orderLineList.add(orderLineDelivery);
                                        }
                                        if (chargeAgainstQuantity < deliveryAmount) {
                                            OrderLineSDO sdo = OrderLineRemoveConverter.converterStatusOne(orderLineSDO);
                                            setDeliveryChargeAgainstAmount(chargeAgainstQuantity, sdo);
                                            orderLineList.add(sdo);
                                        }
                                    }
                                }else {
                                    continue;
                                }
                            }else{
                                log.info("OrderSDO orderSDO 冲销SDO :" + JSONObject.toJSONString(orderSDO));
                                throw  new FunctionException("OTS-05-001-10-16-024");
                            }

                        }
                    }
                }
            }

        }

        if (CollectionUtils.isEmpty(orderLineList)) {
            log.info("orderLineSDOS 外部单号对应的子单集合:"+ JSONObject.toJSONString(orderLineList));
            throw new FunctionException("OTS-05-001-10-16-027");
        }

        return orderLineList.stream().map(OrderLineWriteEntity::of).collect(Collectors.toList());

    }

    private static void setDeliveryChargeAgainstAmount(int chargeAgainstQuantity, OrderLineSDO orderLineDelivery) {
        BigDecimal a = new BigDecimal(orderLineDelivery.getDeliveryAmount());
        int deliveryAmount = a.multiply(new BigDecimal(1000)).intValue();
        if (chargeAgainstQuantity >= deliveryAmount) {
            orderLineDelivery.setDeliveryAmount("0");
        } else {
            BigDecimal b = new BigDecimal(deliveryAmount).divide(new BigDecimal(1000), 3, BigDecimal.ROUND_DOWN);
            BigDecimal c = new BigDecimal(chargeAgainstQuantity).divide(new BigDecimal(1000), 3, BigDecimal.ROUND_DOWN);
            orderLineDelivery.setDeliveryAmount(b.subtract(c).toString());
        }
    }

}
